package keil_map

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
)

type TKeilImageSymbol struct {
	Symbol string ///< Symbol name
	Value  uint32 ///< Value of the symbol
	Size   uint32 ///< Size of the symbol
	OV     string ///< Overlay name
	Owner  string ///< Owner(s) of the symbol
}

func (self *TKeilImageSymbol) String() string {
	return fmt.Sprintf("Symbol: %s, \tValue: %d, \tSize: %d, \tOV: %s, \tOwner: %s",
		self.Symbol, self.Value, self.Size, self.OV, self.Owner)
}

/**
 * @brief: Load symbol information from a string
 * @param s
 * @return
 * @note: 示例:*"g_mlog_report_count_                     0x00000008   Data           1  mem_check.o(.data)"
 *     解析结果:
 *     Symbol: g_mlog_report_count_
 *     Value: 0x00000008
 *     Size: 1
 *     OV: Data
 *     Owner: mem_check.o(.data)
 */
func (self *TKeilImageSymbol) LoadFromString(s string) bool {
	s = strings.TrimSpace(s)
	if len(s) == 0 {
		return false // 输入字符串为空
	}

	// 使用正则表达式按两个及以上空白字符进行分割
	re := regexp.MustCompile(`\s{2,}|\t`)
	fields := re.Split(s, -1)
	if len(fields) < 5 {
		return false // 输入格式不正确
	}

	self.Symbol = strings.TrimSpace(fields[0])
	// 如果名称中有.或或者/，则认为无效
	if strings.ContainsAny(self.Symbol, "./\\") {
		return false
	}

	// 解析 Value（支持十六进制）
	valueStr := strings.TrimSpace(fields[1])
	value64, err := strconv.ParseUint(valueStr, 0, 32)
	if err != nil {
		return false
	}
	self.Value = uint32(value64)

	// OV（如 Data、Code 等）
	self.OV = strings.TrimSpace(fields[2])

	// Size
	fmt.Sscanf(strings.TrimSpace(fields[3]), "%d", &self.Size)
	if self.Size == 0 {
		return false // Size 不记录为0的符号
	}

	// Owner（剩余部分合并）
	self.Owner = strings.TrimSpace(strings.Join(fields[4:], " "))
	return true
}

//-------------------------------------------------------------------------------

func CreateKeilImageSymbolFromString(s string) (*TKeilImageSymbol, error) {
	symbol := new(TKeilImageSymbol)
	if !symbol.LoadFromString(s) {
		symbol = nil
		return nil, fmt.Errorf("failed to load symbol from string: %s", s)
	}

	if symbol.Size == 0 {
		symbol = nil
		return nil, fmt.Errorf("symbol size is zero: %s", s)
	}
	return symbol, nil
}

func FreeKeilImageSymbol(symbol *TKeilImageSymbol) {
	if symbol != nil {
		symbol = nil
	}
}

// ***********************************************************************************

// ***********************************************************************************
